package main

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"strconv"
)

// Node 结构体定义
type Node struct {
	Data chan []byte     `json:"data"`
	Conn *websocket.Conn `json:"conn"`
}

var UsersClient map[int]Node = make(map[int]Node)

// Message 结构体定义
type Message struct {
	UserId      int    `json:"user_id"`
	DistId      int    `json:"dist_id"`
	Cmd         int    `json:"cmd"`
	MessageType int    `json:"message_type"`
	Content     string `json:"content"`
}

// 读消息，读客户端发送给服务端的消息
func read(node Node) {
	for {
		_, message, err := node.Conn.ReadMessage()
		if err != nil {
			log.Println(err)
			return
		}

		var msg Message
		json.Unmarshal(message, &msg)
		if msg.Cmd == 1 {
			if _, ok := UsersClient[msg.DistId]; ok {
				UsersClient[msg.DistId].Data <- message
			}
		} else if msg.Cmd == 2 {
			// 可根据需求添加逻辑
		} else {
			var content = Message{
				Cmd:         3,
				MessageType: 1,
				Content:     "消息类型错误",
			}
			c, _ := json.Marshal(content)
			UsersClient[msg.UserId].Data <- c
		}
	}
}

// 写消息，服务端给客户端发送消息
func write(node Node) {
	for {
		data, ok := <-node.Data
		if ok {
			node.Conn.WriteMessage(websocket.TextMessage, data)
		}
	}
}

func main() {
	// 创建 Gin 引擎
	r := gin.Default()

	// 添加 WebSocket 路由
	r.GET("/websocket", func(c *gin.Context) {
		userId, _ := strconv.Atoi(c.Query("user_id"))
		// 提供一个 websocket 连接
		var upgrader = websocket.Upgrader{
			ReadBufferSize:  1024,
			WriteBufferSize: 1024,
			CheckOrigin: func(r *http.Request) bool {
				return true
			},
		}

		// 1. 创建用户连接
		conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
		if err != nil {
			log.Println(err)
			return
		}

		// 2. 保存用户信息到全局变量中
		var node = Node{
			Data: make(chan []byte, 50),
			Conn: conn,
		}

		conn.WriteMessage(websocket.TextMessage, []byte("欢迎使用 websocket"))

		UsersClient[userId] = node

		// 3. 收发消息（收当前创建连接客户端的消息 ，发给当前连接的客户端发送消息）
		go read(node)
		go write(node)
	})

	// 启动 Gin 服务器
	go r.Run(":8000")

	// 这里可以添加 gRPC 服务器的启动代码
	// ...

	// 保持主 goroutine 运行
	select {}
}
